package com.authine.cloudpivot.ext.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONArray;
import com.authine.cloudpivot.engine.api.facade.OrganizationFacade;
import com.authine.cloudpivot.engine.api.model.organization.DepartmentModel;
import com.authine.cloudpivot.engine.api.model.organization.RoleModel;
import com.authine.cloudpivot.engine.api.model.organization.RoleUserModel;
import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.engine.enums.ErrCode;
import com.authine.cloudpivot.ext.domain.OrgDepartment;
import com.authine.cloudpivot.ext.domain.OrgRoleUser;
import com.authine.cloudpivot.ext.domain.OrgUser;
import com.authine.cloudpivot.ext.mapper.OrgDepartmentMapper;
import com.authine.cloudpivot.ext.mapper.OrgRoleUserMapper;
import com.authine.cloudpivot.ext.mapper.OrgUserMapper;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import com.authine.cloudpivot.web.api.handler.CustomizedOrigin;
import com.authine.cloudpivot.web.api.util.ImportUtil;
import com.authine.cloudpivot.web.api.view.ResponseResult;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * @author chenjq
 * @date 2021/06/09
 */
@Api(value = "角色人员导入接口", tags = "01::EXTAPI::角色人员导入接口")
@RestController
@RequestMapping("/ext/role_user_insert")
@Slf4j
@CustomizedOrigin(level = 1)
public class RoleUserInsertController extends BaseController {

    @Resource
    private OrgUserMapper orgUserMapper;

    @Resource
    private OrgRoleUserMapper orgRoleUserMapper;

    @Resource
    private OrgDepartmentMapper orgDepartmentMapper;

    @ApiOperation("角色导入")
    @PostMapping({"/role_import"})
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<List<String>> roleImport(@RequestBody MultipartFile file) {
        List<String> errorMessages = Lists.newArrayList();
        log.info("========== 开始导入角色 ==========");
        OrganizationFacade organizationFacade = getOrganizationFacade();
        try {
            List<List<Object>> orgRows = excelImport(file, 0);
            log.info("========== orgRows.size(): {} ==========", orgRows.size());
            List<OrgRoleUser> orgRoleUserList = new ArrayList<>();
            int i = 0;
            for (List<Object> orgRow : orgRows) {
                i++;
                OrgRoleUser orgRoleUser = new OrgRoleUser();

                String roleCode = orgRow.get(0).toString();
                String userId = orgRow.get(3).toString();
                UserModel user = organizationFacade.getUser(userId);
                if (null == user) {
                    String errorMessage = "第" + i + "行人员[" + userId + "], " + orgRow.get(2).toString() + "不存在";
                    errorMessages.add(errorMessage);
                    continue;
                }
                if (null == orgRow.get(5)) {
                    String errorMessage = "第" + i + "行[" + orgRow.get(2).toString() + "]角色管理范围不存在";
                    errorMessages.add(errorMessage);
                    log.info("========== roleCode: {}, userId: {} ==========", roleCode, userId);
                    continue;
                }
                String ouScopes = orgRow.get(5).toString();

                RoleModel roleModel = organizationFacade.getRoleByCode(roleCode);
                JSONArray deptIds = (JSONArray) JSONArray.toJSON(ouScopes.split(","));
                JSONArray ouScope = new JSONArray();
                for (int j = 0; j < deptIds.size(); j++) {
                    String dept = deptIds.getString(j);
                    if (dept.contains("ding")) {
                        DepartmentModel rootDepartment = organizationFacade.getRootDepartmentByCorpId(dept);
                        if (null == rootDepartment) {
                            String errorMessage = "第" + i + "行corpId[" + dept + "]," + orgRow.get(2).toString() + "对应的根组织不存在";
                            errorMessages.add(errorMessage);
                            continue;
                        }
                        ouScope.add(rootDepartment.getId());
                    } else {
                        ouScope.add(dept);
                    }
                }

                RoleUserModel roleUserModel = organizationFacade.getRoleUserByRoleIdAndUserId(roleModel.getId(), userId);
                if (null != roleUserModel) {
                    roleUserModel.setOuScope(ouScope.toJSONString());
                    organizationFacade.updateRoleUser(roleUserModel);
                    continue;
                }

                orgRoleUser.setId(UUID.randomUUID().toString().replaceAll("-", ""));
                orgRoleUser.setCreatedTime(new Date());
                orgRoleUser.setModifiedTime(new Date());
                // 设置角色ID
                orgRoleUser.setRoleId(roleModel.getId());
                // 设置用户ID
                orgRoleUser.setUserId(userId);
                // 设置管理范围
                orgRoleUser.setOuScope(ouScope.toJSONString());
                orgRoleUser.setUnitType("USER");
                orgRoleUser.setDeleted(false);
                orgRoleUserList.add(orgRoleUser);
            }
            log.info("========== 开始执行插入操作:{} ==========", orgRoleUserList.size());
            if (CollectionUtil.isNotEmpty(orgRoleUserList)) {
                orgRoleUserMapper.insertByRoleUserList(orgRoleUserList);
            }
            return getOkResponseResult(errorMessages, ErrCode.OK.getErrMsg());
        } catch (IOException e) {
            log.error("========== 角色导入异常 e: {} ==========", e.getMessage());
            return getOkResponseResult(errorMessages, "========== 角色导入异常 e: " + e.getMessage() + " ==========");
        }
    }

    @ApiOperation("excel导入")
    @PostMapping({"/excelUpload"})
    @Transactional(rollbackFor = Exception.class)
    public void roleUserInsert(@RequestBody MultipartFile file) {
        OrganizationFacade organizationFacade = getOrganizationFacade();
        try {
            List<List<Object>> orgRows = excelImport(file, 0);
            List<OrgRoleUser> orgRoleUserList = new ArrayList<>();
            for (int i = 0; i < orgRows.size(); i++) {
                OrgRoleUser orgRoleUser = new OrgRoleUser();
                List<Object> cells = orgRows.get(i);

                String corpId = cells.get(0).toString();
                String roleId = cells.get(4).toString();
                String mobile = cells.get(3).toString();
                String deptName = cells.get(0).toString();
                String name = cells.get(2).toString();

                orgRoleUser.setId(UUID.randomUUID().toString().replaceAll("-", ""));
                orgRoleUser.setCreatedTime(new Date());
                orgRoleUser.setDeleted(false);
                orgRoleUser.setModifiedTime(new Date());
                OrgDepartment orgDepartment = orgDepartmentMapper.selectByCorpIdAndName(corpId, deptName);
                JSONArray jsonArray = new JSONArray();
                jsonArray.add(orgDepartment.getId());
                orgRoleUser.setOuScope(jsonArray.toJSONString());
                RoleModel roleModel = organizationFacade.getRole(roleId);
                orgRoleUser.setRoleId(roleModel.getId());
                orgRoleUser.setUnitType("USER");
                UserModel userModel = organizationFacade.getUserByMobileAndCorpId(mobile, corpId);
                setUser(orgRoleUserList, i, orgRoleUser, name, mobile, corpId, userModel);
            }
            orgRoleUserMapper.insertByRoleUserList(orgRoleUserList);
        } catch (IOException e) {
            log.error("========== e: {} ==========", e.getMessage());
        }
    }

    @ApiOperation("第一书记角色导入")
    @PostMapping({"/role_introduction_first_secretary"})
    @Transactional(rollbackFor = Exception.class)
    public void roleIntroductionFirstSecretary(@RequestBody MultipartFile file) {
        OrganizationFacade organizationFacade = getOrganizationFacade();
        try {
            List<List<Object>> orgRows = excelImport(file, 0);
            List<OrgRoleUser> orgRoleUserList = new ArrayList<>();
            for (int i = 1; i < orgRows.size(); i++) {
                OrgRoleUser orgRoleUser = new OrgRoleUser();
                List<Object> cells = orgRows.get(i);
                String fullName = cells.get(1).toString();
                String post = cells.get(2).toString();
                String unitToWhichOneBelongs = cells.get(4).toString();
                String telephone = cells.get(7).toString();
                List<RoleModel> roleModelList = getOrganizationFacade().getRolesByName(post);
                Example example = new Example(OrgDepartment.class);
                example.createCriteria().andLike("name", "%" + unitToWhichOneBelongs + "%").andEqualTo("corpId", "main");
                List<OrgDepartment> orgDepartments = orgDepartmentMapper.selectByExample(example);
                if (CollectionUtil.isNotEmpty(orgDepartments) && orgDepartments.size() == 1) {
                    OrgDepartment orgDepartment = orgDepartments.get(0);
                    String corpId = orgDepartment.getCorpId();
                    String roleId = roleModelList.get(0).getId();
                    orgRoleUser.setId(UUID.randomUUID().toString().replaceAll("-", ""));
                    orgRoleUser.setCreatedTime(new Date());
                    orgRoleUser.setDeleted(false);
                    orgRoleUser.setModifiedTime(new Date());
                    JSONArray jsonArray = new JSONArray();
                    jsonArray.add(orgDepartment.getId());
                    orgRoleUser.setOuScope(jsonArray.toJSONString());
                    RoleModel roleModel = organizationFacade.getRole(roleId);
                    orgRoleUser.setRoleId(roleModel.getId());
                    orgRoleUser.setUnitType("USER");
                    UserModel userModel = organizationFacade.getUserByMobileAndCorpId(telephone, corpId);
                    setUser(orgRoleUserList, i, orgRoleUser, fullName, telephone, corpId, userModel);
                } else {
                    log.info("========== 第{}行，所属单位：{}， 电话: {} 在系统中未找到多条所属单位或未找到==========", i + 1, unitToWhichOneBelongs, telephone);
                }
            }
//            orgRoleUserMapper.insertByRoleUserList(orgRoleUserList);
        } catch (IOException e) {
            log.error("========== e: {} ==========", e.getMessage());
        }
    }

    private void setUser(List<OrgRoleUser> orgRoleUserList, int i, OrgRoleUser orgRoleUser, String fullName, String telephone, String corpId, UserModel userModel) {
        if (null == userModel) {
            List<OrgUser> orgUsers = orgUserMapper.selectByNameAndCorpId(fullName, corpId);
            if (CollectionUtil.isNotEmpty(orgUsers)) {
                orgRoleUser.setUserId(orgUsers.get(0).getUserId());
                orgRoleUserList.add(orgRoleUser);
            } else {
                log.info("========== 第{}行，姓名：{}， mobile: {} 在系统中未找到==========", i + 1, fullName, telephone);
            }
        } else {
            orgRoleUser.setUserId(userModel.getId());
            orgRoleUserList.add(orgRoleUser);
        }
    }

    /**
     * Excel导入
     *
     * @param file
     *            文件
     * @param sheetNumber
     *            获取第几个sheet的值，从0开始
     * @return
     */
    public List<List<Object>> excelImport(MultipartFile file, Integer sheetNumber) throws IOException {
        ImportUtil importUtil = new ImportUtil();
        List<List<Object>> listob;
        if (file.isEmpty()) {
            throw new IOException("Excel不存在!");
        }
        try {
            InputStream in = file.getInputStream();
            listob = importUtil.getBankListByExcel(in, file.getOriginalFilename(), sheetNumber);
            in.close();
            return listob;
        } catch (Exception e) {
            throw new IOException("Excel导入失败!");
        }
    }

    @ApiOperation(value = "角色人员复制")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "sourceRoleCode", value = "源角色编码", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "targetRoleCode", value = "目标角色编码", required = true, paramType = "query", dataType = "String")}
    )
    @GetMapping(value = "/role_people_copy")
    public void rolePeopleCopy(String sourceRoleCode, String targetRoleCode) {
        OrganizationFacade organizationFacade = getOrganizationFacade();
        RoleModel sourceRole = organizationFacade.getRoleByCode(sourceRoleCode);
        RoleModel targetRole = organizationFacade.getRoleByCode(targetRoleCode);
        List<RoleUserModel> sourceRoleUserModelList = organizationFacade.getRoleUsersByRoleId(sourceRole.getId());
        List<OrgRoleUser> orgRoleUserList = new ArrayList<>();
        sourceRoleUserModelList.forEach(roleUserModel -> {
            OrgRoleUser orgRoleUser = new OrgRoleUser();
            orgRoleUser.setId(UUID.randomUUID().toString().replaceAll("-", ""));
            orgRoleUser.setCreatedTime(new Date());
            orgRoleUser.setDeleted(false);
            orgRoleUser.setModifiedTime(new Date());
            orgRoleUser.setOuScope(roleUserModel.getOuScope());
            orgRoleUser.setRoleId(targetRole.getId());
            orgRoleUser.setUnitType("USER");
            orgRoleUser.setUserId(roleUserModel.getUserId());
            RoleUserModel roleUserModelDb = organizationFacade.getRoleUserByRoleIdAndUserId(targetRole.getId(), roleUserModel.getUserId());
            if (null == roleUserModelDb) {
                orgRoleUserList.add(orgRoleUser);
            }
        });
        orgRoleUserMapper.insertByRoleUserList(orgRoleUserList);
    }

}
